#import <SpringBoard/SBApplication.h>
#import <SpringBoard/SBApplicationController.h>
#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>
#import <objc/runtime.h>
#import <UIKit/UIApplication.h>
#import <LockInfo/Plugin.h>

#import "framework/FWCommon.h"
#import "framework/FWApplication.h"
#import "framework/FWIconDotView.h"
#import "framework/FWDotView.h"
#import "framework/FWColorIconView.h"
#import "framework/FWRoundedLabel.h"

#import "PITaskView.h"
#import "PITaskPlugin.h"
#import "PITaskListAccess.h"
#import "PIIntegration.h"


@implementation PITaskView

@synthesize action, flag, tree, context, overdue, native;


// ******************************************************************************************
#pragma mark -
#pragma mark Initialisation and object management

static CGRect const flagSize = CGRectMake(0, 0, kFWListViewMarkerSize, kFWListViewMarkerSize);

- (id)initWithFrame:(CGRect)frame theme:(LITheme*)theme application:(FWApplication*)app
{
    if ((self = [super initWithFrame:frame theme:theme])) {
        self.largestIcon = kFWListViewMarkerSpace;
        
        self.action = [[[FWIconDotView alloc] initWithFrame:CGRectMake(0, 0, kFWListViewMarkerSpace, kFWListViewMarkerSpace)
                                                      inset:(kFWListViewMarkerSpace - kFWListViewMarkerSize) / 2] autorelease];
        self.action.backgroundColor = [UIColor clearColor];
        self.action.beveled = YES;

        self.flag = [[[UIImageView alloc] initWithFrame:flagSize] autorelease];
        self.flag.image = [UIImage imageWithContentsOfFile:[PIIntegration iconPathForSmallFlag:app]];
        self.flag.backgroundColor = [UIColor clearColor];

        self.tree = [[[FWColorIconView alloc] initWithFrame:flagSize] autorelease];

        NSString* contextPath = [app.pluginBundle pathForResource:@"context" ofType:@"png"];
        self.context = [[[UIImageView alloc] initWithFrame:flagSize] autorelease];
        self.context.image = [UIImage imageWithContentsOfFile:contextPath];
        self.context.backgroundColor = [UIColor clearColor];

        NSString* overduePath = [app.pluginBundle pathForResource:@"overdue" ofType:@"png"];
        self.overdue = [[[FWColorIconView alloc] initWithFrame:flagSize] autorelease];
        self.overdue.icon = overduePath;

        self.native = [[[FWColorIconView alloc] initWithFrame:flagSize] autorelease];
        self.native.icon = [app.pluginBundle pathForResource:@"native" ofType:@"png"];

        [self addSubview:self.native];
        [self addSubview:self.context];
        [self addSubview:self.tree];
        [self addSubview:self.action];
        [self addSubview:self.overdue];
        [self addSubview:self.flag];
        
        self.flags = [NSArray arrayWithObjects:
                      self.action,
                      self.tree,
                      self.overdue,
                      self.native,
                      self.context,
                      self.flag,
                      nil];
    }
    
    return self;
}

-(void)dealloc 
{
    [native release];
    [action release];
    [flag release];
    [tree release];
    [context release];
    [overdue release];
    
    [super dealloc];
}


// ******************************************************************************************
#pragma mark -
#pragma mark Updating and presenting information to the user

- (void)setViewForTask:(PITask*)task theme:(LITheme*)theme application:(FWApplication*)app style:(kPITaskViewStyle)style showShortDates:(ShortDatesOptions)showShortDates showDetailLine:(BOOL)showDetailLine showIcons:(BOOL)showIcons showEmoji:(BOOL)showEmoji showOverdue:(BOOL)showOverdue showChildIcons:(BOOL)showChildIcons lowColour:(BOOL)lowColour sourceIcon:(ShowSourceIconOptions)sourceIcon
{
    NSBundle* bundle = [NSBundle bundleForClass:[self class]];
    viewStyle = style;
    
    NSString* nameValue = task.title;
    if (showEmoji)
        nameValue = [PIIntegration stringForTitle:nameValue withIcon:task.icon withProjectIcon:task.calendarIcon];
    
    NSString* due = nil;
    NSString* shortDue = nil;

    NSDate* startDateValue = task.startDate;
    NSDate* dueDateValue = task.dueDate;
    NSDate *now = [NSDate date];

    BOOL isOverdue = NO;
    if (showOverdue && !dueDateValue.isNull && [dueDateValue isEarlierThanDate:now]) 
        isOverdue = YES;
    
    if (showDetailLine) {		
        if (dueDateValue.isNull && startDateValue.isNull) {
            due = localize(bundle, @"Date/No Due Date");
        }
        else {
            BOOL showTime = !task.isAllDay;
            
            // If start and due are the same day then only display the one date, otherwise display the range
            if (FWIsLocalDateSameDay(startDateValue, dueDateValue)) {
                due = FWLocalDateStringForUTCDate(dueDateValue, FWDateFormatterNormalFormat, showTime, bundle);
                shortDue = FWLocalDateStringForUTCDate(dueDateValue, FWDateFormatterCompressedFormat, showTime, bundle);
            }
            else {
                due = [NSString stringWithFormat:@"%@ \u2014 %@",
                       FWLocalDateStringForUTCDate(startDateValue, FWDateFormatterNormalFormat, NO, bundle),
                       FWLocalDateStringForUTCDate(dueDateValue, FWDateFormatterNormalFormat, showTime, bundle)];
                shortDue = [NSString stringWithFormat:@"%@ \u2014 %@",
                            FWLocalDateStringForUTCDate(startDateValue, FWDateFormatterCompressedFormat, NO, bundle),
                            FWLocalDateStringForUTCDate(dueDateValue, FWDateFormatterCompressedFormat, showTime, bundle)];
            }
            
            if (showShortDates == ShortDatesAlways)
                due = shortDue;
            else if (showShortDates == ShortDatesNever)
                shortDue = due;
        }
    }
    
    // Now set the values
    self.summaryText.style = theme.summaryStyle;
    self.summaryText.text = nameValue;
    
    UIColor* importanceColor = [PIIntegration colorForImportance:task.importance application:app];
    UIColor* importanceBGColor = [PIIntegration colorBGForImportance:task.importance application:app];

    // Validate the colours. If the combination doesn't make sense then ignore it!
    if (FWIsColorDark(importanceBGColor)) {
        if (FWIsColorDark(importanceColor))
            importanceColor = [UIColor whiteColor];
    }
    else {
        if (!FWIsColorDark(importanceColor))
            importanceColor = [UIColor blackColor];
    }
    
    if (importanceBGColor != nil) {
        self.dot.color = task.calendarColor;
        self.dot.hidden = NO;
    }
    else
        self.dot.hidden = YES;

    // If we have a project value then display it in the priority field
    UITextAlignment alignment = UITextAlignmentCenter;
    NSString* priority = task.priority;
    if (!priority || (priority.length == 0)) {
        priority = task.project;
        alignment = UITextAlignmentLeft;
    }

    if (due && priority && (priority.length > 0)) {
        self.highlightText.label.text = priority;
        self.highlightText.label.textAlignment = alignment;
        self.highlightText.label.font = theme.detailStyle.font;
        self.highlightText.hidden = NO;
        
        if (lowColour) {
            [self.highlightText setRoundedColor:theme.detailStyle.textColor];
            self.highlightText.textColor = FWIsColorDark(theme.detailStyle.textColor) ? [UIColor whiteColor] : [UIColor blackColor];
        }
        else {
            self.highlightText.textColor = importanceColor;
            [self.highlightText setRoundedColor:importanceBGColor];
        }
    }
    else
        self.highlightText.hidden = YES;

    if (task.isFlagged && showIcons) {
        self.flag.hidden = NO;
    }
    else
        self.flag.hidden = YES;

    if (isOverdue && showIcons) {
        self.overdue.hidden = NO;
        self.overdue.color = [PIIntegration colorForOverdue:app];
    }
    else
        self.overdue.hidden = YES;

    if ((task.contextClassification == ContextClassificationInContext) && showIcons) {
        self.context.hidden = NO;
    }
    else
        self.context.hidden = YES;
    
    if (due) {
        if (isOverdue) {
            self.detailText.style = [[theme.detailStyle copy] autorelease];
            self.detailText.style.textColor = [PIIntegration colorForOverdue:app];
        }
        else
            self.detailText.style = theme.detailStyle;
        
        self.detailText.text = due;
        self.detailText.hidden = NO;
        self.detailTextAlternate = shortDue;
    }
    else
        self.detailText.hidden = YES;
    
    NSString* actionIcon = [PIIntegration iconPathForAction:task.action application:app];
    if (showIcons && actionIcon) {
        self.action.color = [PIIntegration colorBGForAction:task.action application:app];
        self.action.icon = actionIcon;
        self.action.hidden = NO;
    }
    else
        self.action.hidden = YES;

    if (task.isNative && ((sourceIcon == ShowSourceIconOptionsBoth) || (sourceIcon == ShowSourceIconOptionsIOSOnly))) {
        self.native.icon = [bundle pathForResource:@"native" ofType:@"png"];
        self.native.hidden = NO;
    }
    else if (!task.isNative && ((sourceIcon == ShowSourceIconOptionsBoth) || (sourceIcon == ShowSourceIconOptionsPIOnly))) {
        self.native.icon = [bundle pathForResource:@"pi" ofType:@"png"];
        self.native.hidden = NO;
    }
    else
        self.native.hidden = YES;

    if (!self.native.isHidden)
        self.native.color = self.summaryText.style.textColor;

    if (task.isParent && showChildIcons && showIcons) {
        self.tree.hidden = NO;
        self.tree.color = importanceBGColor ? importanceBGColor : [UIColor whiteColor];
        self.tree.icon = [PIIntegration iconPathForParent:app];
    }
    else if (task.isChild && showChildIcons && showIcons) {
        self.tree.hidden = NO;
        self.tree.color = importanceBGColor ? importanceBGColor : [UIColor whiteColor];
        self.tree.icon = [PIIntegration iconPathForChild:app];
    }
    else
        self.tree.hidden = YES;
        
    [self setNeedsLayout];
}


// ******************************************************************************************
#pragma mark -
#pragma mark Layout support

- (void)layoutSubviews
{
    [super layoutSubviews];
    
    // Do we need to move the highlight view?
    if (!self.highlightText.isHidden) {
        if (viewStyle == kPITaskViewStyleTimeAtStart) {
            CGRect highlightRect = self.highlightText.frame;
            CGRect summaryRect = self.summaryText.frame;
            CGRect detailRect = self.detailText.frame;
            
            if (highlightRect.origin.x <= summaryRect.origin.x) {
                // Move to the end of the detail line
                detailRect.origin.x = highlightRect.origin.x;
                highlightRect.origin.x += detailRect.size.width + kFWListViewSeparatorSize;
                
                self.highlightText.frame = highlightRect;
                self.detailText.frame = detailRect;
            }
        }
    }

    if (self.detailText.isHidden) {
        // Place the dot half way up the title line
        CGRect dotRect = self.dot.frame;
        CGFloat pos = (self.summaryText.frame.size.height - dotRect.size.height) / 2;
        
        self.dot.frame = CGRectMake(dotRect.origin.x,
                                    self.summaryText.frame.origin.y + pos,
                                    dotRect.size.width,
                                    dotRect.size.height);
    }
}


// ******************************************************************************************
#pragma mark -
#pragma mark Row height support

+ (CGFloat)heightOfSummaryRowWithFont:(UIFont*)font withHeader:(BOOL)header withFollowingRow:(BOOL)following
{
    CGFloat height = [FWListView heightOfSummaryRowWithFont:font withHeader:header withFollowingRow:following];
    
    // If no following line and the text area is smaller than the marker, use the marker size
    if (!following && (height <= kFWListViewMarkerSpace))
        height = kFWListViewMarkerSpace + 1;

    return height;
}

@end
